/**
 *	@file	fld_pkthrec.c
 *	@brief	フィールドポケスロンレコード閲覧ウィンドウ表示
 *	@author	Miyuki Iwasawa
 *	@date	08.11.19
 */

#include "common.h"
#include "fld_bmp.h"
#include "fntsys.h"
#include "talk_msg.h"
#include "fieldmap.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/window.h"
#include "system/fontproc.h"
#include "system/wipe.h"
#include "system/buflen.h"
#include "system/pm_str.h"
#include "system/arc_util.h"
#include "system/pmfprint.h"
#include "system/snd_tool.h"
#include "system/wordset.h"
#include "gflib/strbuf.h"
#include "gflib/strbuf_family.h"
#include "field/fieldsys.h"
#include "field/field.h"
#include "field/field_event.h"

#include "field/eventflag.h"
#include "sysflag.h"
#include "savedata/pkthln_svdata.h"
#include "msgdata/msg_pkth_rec.h"
#include "msgdata/msg.naix"
#include "fld_pkthrec.h"

enum{
 SEQ_INIT,
 SEQ_MAIN,
 SEQ_EXIT,
};

#define PKTH_REC_ID_PLAY			(0)		///<プレイ回数
#define PKTH_REC_ID_1ST				(1)		///<ポケスロン１位
#define PKTH_REC_ID_LOWEST			(2)		///<ポケスロン最下位
#define PKTH_REC_ID_GET_BONUS		(3)		///<ボーナス獲得回数
#define PKTH_REC_ID_GAME_1ST		(4)		///<競技１位
#define PKTH_REC_ID_GAME_LOWEST		(5)		///<競技最下位
#define PKTH_REC_ID_SIO_PLAY		(6)		///<通信プレイ回数
#define PKTH_REC_ID_SIO_1ST			(7)		///<通信１位
#define PKTH_REC_ID_SIO_LOWEST		(8)		///<通信最下位
#define PKTH_REC_ID_PLAY_TIME		(9)		///<プレイ時間

#define PKTH_REC_ID_HURDLE_1ST		(10)	///<ハードル１位
#define PKTH_REC_ID_FLAG_1ST		(11)	///<フラッグ１位
#define PKTH_REC_ID_CIRCLE_1ST		(12)	///<すもう１位
#define PKTH_REC_ID_BLOCK_1ST		(13)	///<かわらわり１位
#define PKTH_REC_ID_CATCH_1ST		(14)	///<UFO１位
#define PKTH_REC_ID_TRAMPOLINE_1ST	(15)	///<トランポリン１位
#define PKTH_REC_ID_MARATHON_1ST	(16)	///<リレー１位
#define PKTH_REC_ID_WRESTLING_1ST	(17)	///<レスリング１位
#define PKTH_REC_ID_YUKIDAMA_1ST	(18)	///<雪玉１位
#define PKTH_REC_ID_SHOT_1ST		(19)	///<サッカー１位

#define PKTH_REC_ID_TOUCH_NUM		(20)	///<タッチ回数
#define PKTH_REC_ID_DUSH_NUM		(21)	///<ダッシュ回数
#define PKTH_REC_ID_JUMP_NUM		(22)	///<ジャンプ回数
#define PKTH_REC_ID_TACKLE_NUM		(23)	///<体当たり回数
#define PKTH_REC_ID_CHANGE_NUM		(24)	///<交代回数
#define PKTH_REC_ID_SUISIDE_NUM		(25)	///<自滅回数
#define PKTH_REC_ID_GET_POINT		(26)	///<獲得したポイント
#define PKTH_REC_ID_ERROR_NUM		(27)	///<エラー回数
#define PKTH_REC_ID_FALL_NUM		(28)	///<落ちた回数

#define	BMPL_RECWIN_CGX		( 1 )
#define	BMPL_RECWIN_PAL		( FLD_SYSFONT_PAL )

#define WORDSET_REC_BUFLEN	(16)
#define WORDSET_REC_BUFNUM	(3)
#define REC_MSG_BUFLEN		(128)	///<メッセージ展開バッファ長

#define LINE_SY	(8)
#define NAME_X	(8)
#define VALUE_X	(8)

#define BMPL_RECWIN_SX	(28)
#define BMPL_RECWIN_SY	(22)

#define PRINT_COL	(GF_PRINTCOLOR_MAKE(FBMP_COL_BLACK,FBMP_COL_BLK_SDW,FBMP_COL_WHITE))

//レコード出現フラグテーブル
static u8 DATA_RecordAppearTbl[] = {
	0,//プレイ回数
	1,//ポケスロン１位
	2,//ポケスロン最下位
	25,//ボーナス獲得回数
	21,//競技１位
	22,//競技最下位
	0,//通信プレイ回数
	19,//通信１位
	20,//通信最下位
	27,//プレイ時間

	5,//ハードル１位
	7,//フラッグ１位
	18,//すもう１位
	8,//かわらわり１位
	9,//UFO１位
	17,//トランポリン１位
	6,//リレー１位
	16,//レスリング１位
	10,//雪玉１位
	24,//サッカー１位

	26,//タッチ回数
	3,//ダッシュ回数
	4,//ジャンプ回数
	14,//体当たり回数
	23,//交代回数
	13,//自滅回数
	11,//獲得したポイント
	12,//エラー回数
	15,//落ちた回数
};

typedef struct _PKTH_REC_EVENT{
	int	seq;
	int mode;

	FIELDSYS_WORK*	fsys;
	GF_BGL_INI* bgl;
	GF_BGL_BMPWIN	win;
	PKTHLN_SV_DATA_PTR pkth_sv;
	const PKTH_RNK_DATA* rank_sv;

	MSGDATA_MANAGER *msg_man;
	WORDSET* wset;	//ワーク
	STRBUF*	s_tmp;	//汎用
	STRBUF*	s_buf;	//汎用
	STRBUF*	s_xvalue;	//汎用
	STRBUF*	s_unknown;	//汎用
}PKTH_REC_EVENT;

static BOOL PkthRecViewEvent_Main( GMEVENT_CONTROL *ev );

static BOOL sub_InputCheck(PKTH_REC_EVENT* wk);

static void sub_ResInit(PKTH_REC_EVENT* wk);
static void sub_ResRelease(PKTH_REC_EVENT* wk);
static void sub_RecordWrite(PKTH_REC_EVENT* wk,int mode);
static void sub_HideLineDraw(PKTH_REC_EVENT* wk,int oy);
static void sub_RecordLineDraw(PKTH_REC_EVENT* wk,int oy, int id);

static u32 sub_RecDataGet(const PKTH_RNK_DATA* sv,int id);

//--------------------------------------------------------------
/**
 * @brief	ポケスロンレコード画面サブイベント呼び出し
 * @param	event	GMEVENT_CONTROL*
 * @retval	nothing
 */
//--------------------------------------------------------------
void EventCmd_PkthRecViewCall( GMEVENT_CONTROL *event,int mode)
{
	FIELDSYS_WORK *fsys = FieldEvent_GetFieldSysWork( event );
	PKTH_REC_EVENT* wk = sys_AllocMemory( HEAPID_WORLD,sizeof(PKTH_REC_EVENT));

	wk->seq = 0;
	wk->mode = mode;
	wk->bgl = fsys->bgl;
	wk->fsys = fsys;
	wk->pkth_sv = PkthlnSv_GetSaveData(fsys->savedata);
	wk->rank_sv = PkthlnSv_GetRnkDataCnst(wk->pkth_sv);

	FieldEvent_Call( fsys->event, PkthRecViewEvent_Main, wk);
}

//--------------------------------------------------------------
/**
 * @brief	ギネスランキング画面イベント
 * @param	ev	GMEVENT_CONTROL *
 * @retval	BOOL	TRUE=イベント終了
 */
//--------------------------------------------------------------
static BOOL PkthRecViewEvent_Main( GMEVENT_CONTROL *ev )
{
	FIELDSYS_WORK *fsys = FieldEvent_GetFieldSysWork( ev );
	PKTH_REC_EVENT *wk = FieldEvent_GetSpecialWork( ev );

	switch(wk->seq){
	case SEQ_INIT:
		sub_ResInit(wk);
		sub_RecordWrite(wk,wk->mode);
		wk->seq++;
		break;
	case SEQ_MAIN:
		if(!sub_InputCheck(wk)){
			break;
		}
		sub_ResRelease(wk);
		sys_FreeMemoryEz(wk);
		return TRUE;
	}
	return FALSE;
}

/**
 *	@brief	入力チェック
 */
static BOOL sub_InputCheck(PKTH_REC_EVENT* wk)
{
	if(GF_TP_GetTrg()){
		Snd_SePlay(SEQ_SE_DP_DECIDE);
		KeyTouchStatus_SetTouchOrKey(&wk->fsys->KeyTouchStatus,APP_KTST_TOUCH);
		return TRUE;
	}
	if(sys.trg & PAD_BUTTON_KTST_CHG){
		KeyTouchStatus_SetTouchOrKey(&wk->fsys->KeyTouchStatus,APP_KTST_KEY);
	}
	if(sys.trg & (PAD_BUTTON_DECIDE|PAD_BUTTON_CANCEL)){
		Snd_SePlay(SEQ_SE_DP_DECIDE);
		return TRUE;
	}
	return FALSE;
}

/**
 *	@brief	ウィンドウ初期化
 */
static void sub_ResInit(PKTH_REC_EVENT* wk)
{
	GF_BGL_BmpWinAdd(
		wk->bgl, &wk->win, FLD_MBGFRM_FONT, 2, 1,
		BMPL_RECWIN_SX, BMPL_RECWIN_SY, BMPL_RECWIN_PAL, BMPL_RECWIN_CGX );

	// メニューウィンドウのグラフィックをセット
	MenuWinGraphicSet( wk->bgl, FLD_MBGFRM_FONT, MENU_WIN_CGX_NUM, MENU_WIN_PAL, 0, HEAPID_FIELD );
	// メニューウィンドウを描画
	BmpMenuWinWrite( &wk->win, WINDOW_TRANS_OFF, MENU_WIN_CGX_NUM, MENU_WIN_PAL );
	// 指定範囲を塗りつぶし
	GF_BGL_BmpWinDataFill( &wk->win, FBMP_COL_WHITE );

	wk->msg_man = MSGMAN_Create(MSGMAN_TYPE_NORMAL,ARC_MSG,
					NARC_msg_pkth_rec_dat,HEAPID_FIELD);

	wk->wset = WORDSET_CreateEx(WORDSET_REC_BUFNUM,WORDSET_REC_BUFLEN,HEAPID_FIELD);
	wk->s_tmp = STRBUF_Create(REC_MSG_BUFLEN,HEAPID_FIELD);
	wk->s_buf = STRBUF_Create(REC_MSG_BUFLEN,HEAPID_FIELD);

	wk->s_xvalue = MSGMAN_AllocString(wk->msg_man,msg_value_none);
	wk->s_unknown = MSGMAN_AllocString(wk->msg_man,msg_rec00);
}

/**
 *	@brief	ウィンドウ廃棄
 */
static void sub_ResRelease(PKTH_REC_EVENT* wk)
{
	STRBUF_Delete( wk->s_unknown );
	STRBUF_Delete( wk->s_xvalue );
	STRBUF_Delete( wk->s_buf );
	STRBUF_Delete( wk->s_tmp );
	WORDSET_Delete( wk->wset );
	MSGMAN_Delete( wk->msg_man );

	BmpMenuWinClear( &wk->win, WINDOW_TRANS_OFF );
	GF_BGL_BmpWinDel( &wk->win );
	GF_BGL_LoadScreenV_Req( wk->bgl, FLD_MBGFRM_FONT );
}

/**
 *	@brief	そのレコードのオープンフラグが有効かどうか？
 */
static BOOL sub_IsRecordEnable(PKTH_REC_EVENT* wk,int id)
{
	int idx;

	idx = DATA_RecordAppearTbl[id];
	if(idx == 0){	//無条件閲覧可
		return TRUE;
	}
	return PkthlnSv_GetRankingAppear ( wk->pkth_sv, idx-1 );
}

/**
 *	@brief	レコード書き込み
 */
static void sub_RecordWrite(PKTH_REC_EVENT* wk,int mode)
{
	int i,id,oy;
	static const num[] = {10,10,9};
	for(i = 0 ; i < num[mode] ; i++){
		id = mode*10+i;
		oy = 16*i+LINE_SY;

		if(sub_IsRecordEnable(wk,id)){
			sub_RecordLineDraw(wk,oy,id);
		}else{
			sub_HideLineDraw(wk,oy);
		}
	}
	GF_BGL_BmpWinOnVReq(&wk->win);
	GF_BGL_LoadScreenV_Req( wk->bgl, FLD_MBGFRM_FONT );
}

/**
 *	@brief	隠しライン描画
 */
static void sub_HideLineDraw(PKTH_REC_EVENT* wk,int oy)
{
	GF_STR_PrintColor( &wk->win, FONT_SYSTEM, wk->s_unknown,
		NAME_X,oy, MSG_NO_PUT, PRINT_COL, NULL );
	GF_STR_PrintColor( &wk->win, FONT_SYSTEM, wk->s_xvalue,
		VALUE_X,oy, MSG_NO_PUT, PRINT_COL, NULL );
}

/**
 *	@brief	レコードライン描画
 */
static void sub_RecordLineDraw(PKTH_REC_EVENT* wk,int oy, int id)
{
	u32 rec,ofs;

	MSGMAN_GetString(wk->msg_man,msg_rec01+id,wk->s_buf);
	GF_STR_PrintColor( &wk->win, FONT_SYSTEM, wk->s_buf,
		NAME_X,oy, MSG_NO_PUT, PRINT_COL, NULL );

	rec = sub_RecDataGet(wk->rank_sv,id);

	if(rec >= 9999999){
		OS_Printf("PkthRecordOver ID%d = %d\n",id,rec);
		rec = 9999999;
	}
	if(id == PKTH_REC_ID_PLAY_TIME){
		u16 h,m;
		MSGMAN_GetString(wk->msg_man,msg_value_time,wk->s_tmp);

		h = rec/60;
		m = rec%60;
		if(h > 999){
			h = 999;
		}
		WORDSET_RegisterNumber( wk->wset, 0,
			h , 3, NUMBER_DISPTYPE_SPACE, NUMBER_CODETYPE_DEFAULT );
		WORDSET_RegisterNumber( wk->wset, 1,
			m , 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_DEFAULT );
		WORDSET_ExpandStr( wk->wset, wk->s_buf ,wk->s_tmp);
	}else{
		STRBUF_SetNumber(wk->s_buf,rec,7,NUMBER_DISPTYPE_SPACE,NUMBER_CODETYPE_DEFAULT);
	}
	ofs = (BMPL_RECWIN_SX*8)-FontProc_GetPrintStrWidth(FONT_SYSTEM,wk->s_buf,0);
	GF_STR_PrintColor( &wk->win, FONT_SYSTEM, wk->s_buf,
		ofs-VALUE_X,oy, MSG_NO_PUT, PRINT_COL, NULL );
}

/**
 *	@brief	データ取得
 */
static u32 sub_RecDataGet(const PKTH_RNK_DATA* sv,int id)
{
	if(id >= PKTH_REC_ID_HURDLE_1ST && id <=  PKTH_REC_ID_SHOT_1ST){
		return sv->EvtWinNum[id-PKTH_REC_ID_HURDLE_1ST];
	}

	switch(id){
	case PKTH_REC_ID_PLAY:
		return sv->AlonePlay;
	case PKTH_REC_ID_1ST:
		return sv->AloneWin;
	case PKTH_REC_ID_LOWEST:
		return sv->AloneLose;
	case PKTH_REC_ID_GET_BONUS:
		return sv->BonusNum;
	case PKTH_REC_ID_GAME_1ST:
		{
			int i,rec = 0;
			for(i = 0;i < 10;i++){
				rec += sv->EvtWinNum[i];
			}
			return rec;
		}
	case PKTH_REC_ID_GAME_LOWEST:
		return sv->EvtLoseNum;
	case PKTH_REC_ID_SIO_PLAY:
		return sv->CommPlay;
	case PKTH_REC_ID_SIO_1ST:
		return sv->CommWin;
	case PKTH_REC_ID_SIO_LOWEST:
		return sv->CommLose;
	case PKTH_REC_ID_PLAY_TIME:
		return sv->PlayMinute;
	case PKTH_REC_ID_TOUCH_NUM:
		return sv->TouchNum;
	case PKTH_REC_ID_DUSH_NUM:
		return sv->PokeDash;
	case PKTH_REC_ID_JUMP_NUM:
		return sv->PokeJump;
	case PKTH_REC_ID_TACKLE_NUM:
		return sv->PokeAttack;
	case PKTH_REC_ID_CHANGE_NUM:
		return sv->PokeChange;
	case PKTH_REC_ID_SUISIDE_NUM:
		return sv->OwnGoal;
	case PKTH_REC_ID_GET_POINT:
		return sv->PointGet;
	case PKTH_REC_ID_ERROR_NUM:
		return sv->PokeFail;
	case PKTH_REC_ID_FALL_NUM:
		return sv->PokeFall;
	}
	return 0;
}